package com.leyou.search.service.impl;

import com.leyou.common.dto.PageDTO;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.search.entity.Goods;
import com.leyou.search.repository.GoodsRepository;
import com.leyou.search.service.IndexService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ShenMin
 * @date 2021/7/21 17:40
 * @description
 */
@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    ItemClient itemClient;
    @Autowired
    GoodsRepository goodsRepository;

    public void loadData() {

        try {
            this.goodsRepository.deleteIndex();
        } catch (Throwable e) {
        }
        this.goodsRepository.createIndex("{\n" +
                "  \"settings\": {\n" +
                "    \"analysis\": {\n" +
                "      \"analyzer\": {\n" +
                "        \"my_pinyin\": {\n" +
                "          \"tokenizer\": \"ik_smart\",\n" +
                "          \"filter\": [\n" +
                "            \"py\"\n" +
                "          ]\n" +
                "        }\n" +
                "      },\n" +
                "      \"filter\": {\n" +
                "        \"py\": {\n" +
                "\t\t  \"type\": \"pinyin\",\n" +
                "          \"keep_full_pinyin\": true,\n" +
                "          \"keep_joined_full_pinyin\": true,\n" +
                "          \"keep_original\": true,\n" +
                "          \"limit_first_letter_length\": 16,\n" +
                "          \"remove_duplicated_term\": true\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  },\n" +
                "  \"mappings\": {\n" +
                "    \"properties\": {\n" +
                "      \"id\": {\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"suggestion\": {\n" +
                "        \"type\": \"completion\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"title\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"image\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"index\": false\n" +
                "      },\n" +
                "      \"updateTime\":{\n" +
                "        \"type\": \"date\"\n" +
                "      },\n" +
                "      \"specs\":{\n" +
                "        \"type\": \"nested\",\n" +
                "        \"properties\": {\n" +
                "          \"name\":{\"type\": \"keyword\" },\n" +
                "          \"value\":{\"type\": \"keyword\" }\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  }\n" +
                "}");
        List<Goods> goodsList;
        int page = 1;

        while (true) {
            PageDTO<SpuDTO> spuDTOPageDTO = itemClient.listSpuByPage(null, null, null, page++, 10, null);
            if (null == spuDTOPageDTO || CollectionUtils.isEmpty(spuDTOPageDTO.getItems())) {
                break;
            }
            goodsList = spuDTOPageDTO.getItems().stream().map(this::buildData).collect(Collectors.toList());
            this.goodsRepository.saveAll(goodsList);
            if (page > spuDTOPageDTO.getTotalPage()) {
                break;
            }
        }

    }

    public Goods buildData(SpuDTO spuDTO) {
        Goods goods = new Goods();
        BeanUtils.copyProperties(spuDTO, goods);
        goods.setCategoryId(spuDTO.getCid3());
        goods.setUpdateTime(new Date());
        List<SkuDTO> skuDTOList = itemClient.querySkuListBySpuIds(spuDTO.getId());
        if (!CollectionUtils.isEmpty(skuDTOList)) {
            goods.setImage(StringUtils.substringBefore(skuDTOList.get(0).getImages(), ","));
        }
        Set<Long> priceSet = new HashSet<>();
        goods.setSold(0L);
        ArrayList<String> suggestions = new ArrayList<>();
        suggestions.add(StringUtils.substringBefore(spuDTO.getBrandName(), "（"));
        suggestions.add(StringUtils.substringAfterLast(spuDTO.getCategoryName(), "/"));
        suggestions.add(spuDTO.getName());
        goods.setSuggestion(suggestions);
        for (SkuDTO skuDTO : skuDTOList) {
            priceSet.add(skuDTO.getPrice());
            goods.setSold(goods.getSold() + skuDTO.getSold());
        }
        goods.setPrices(priceSet);
        List<SpecParamDTO> specParamDTOS = itemClient.listSpecParamBySpuId(spuDTO.getId(), true);

        List<Map<String, Object>> specs = specParamDTOS.stream().map(specParamDTO -> {
            Map<String, Object> map = new HashMap<>();
            map.put("name", specParamDTO.getName());
            map.put("value", chooseSegment(specParamDTO));
            return map;
        }).collect(Collectors.toList());
        goods.setSpecs(specs);
        return goods;
    }

    @Override
    public void modifyGoods(Boolean saleable, Long id) {
        if (saleable) {
            PageDTO<SpuDTO> spuDTOPageDTO = this.itemClient.listSpuByPage(null, null, id, 1, 1, true);
            this.goodsRepository.save(this.buildData(spuDTOPageDTO.getItems().get(0)));
        } else {
            this.goodsRepository.deleteById(id);
        }
    }

    private Object chooseSegment(SpecParamDTO specParamDTO) {
        Object value = specParamDTO.getValue();
        if (value == null || StringUtils.isBlank(value.toString())) {
            return "其他";
        }
        if (!specParamDTO.getNumeric() || StringUtils.isBlank(specParamDTO.getSegments()) || value instanceof Collection) {
            return value;
        }
        double val = parseDouble(value.toString());
        String result = "其它";
        for (String segment : specParamDTO.getSegments().split(",")) {
            String[] segments = segment.split("-");
            double begin = Double.parseDouble(segments[0]);
            double end = Double.MAX_VALUE;
            if (segments.length == 2) {
                end = Double.parseDouble(segments[1]);
            }
            if (val >= begin && val < end) {
                if (segments.length == 1) {
                    result = segments[0] + specParamDTO.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segments[1] + specParamDTO.getUnit() + "以下";
                } else {
                    result = segment + specParamDTO.getUnit();
                }
                break;
            }
        }
        return result;
    }


    private double parseDouble(String str) {
        try {
            return Double.parseDouble(str);
        } catch (Exception e) {
            return 0;
        }
    }
}
